import React from 'react';
import ReactEcharts from 'echarts-for-react';
import { Guid } from '../utils';
import { rgbaChangeAlpha } from '../utils/colors';
import Label from '../tags';
import { LABEL_TYPES } from '../utils/constant';
import { IbrushData, ILabel, ITimeSeriesProps } from '../utils/types';

const TimeSeries = (props: ITimeSeriesProps) => {
  const { topic, title, secondKey, secondData, value, label, defalutData, className = 'time-series', style, onNodeClick, onBrushChange } = props;

  const valueData = React.useMemo(() => {
    const x = value[0].map((it: any) => {
      return it[0];
    });
    const y = value[0].map((it: any) => {
      return it[1];
    });

    return {
      x,
      y,
    };
  }, [value]);

  const tsRef = React.useRef<ReactEcharts>(null);
  // 判断是否为首次渲染
  const firstRender = React.useRef<boolean>(true);

  const [curLabel, setCurLabel] = React.useState<ILabel>({});
  const [curIndex, setCurIndex] = React.useState<number>(0);
  const curLabelRef = React.useRef<ILabel>(curLabel);
  const curIndexRef = React.useRef<number>(curIndex);

  const [brushData, setBrushData] = React.useState<IbrushData[]>([]);
  const brushDataRef = React.useRef<IbrushData[]>(brushData);

  const secondDataRef = React.useRef<IbrushData[]>([]);

  const option = React.useMemo(() => {
    return {
      tooltip: {
        trigger: 'axis',
      },
      toolbox: {
        show: false,
      },
      brush: {
        toolbox: ['lineX', 'keep', 'clear'],
        brushType: 'lineX',
        brushMode: 'multiple',
        brushLink: 'all',
        brushStyle: {
          borderWidth: 1,
          color: 'rgba(120,140,180,0.1)',
          borderColor: 'rgba(120,140,180,0.4)',
        },
        xAxisIndex: 0,
        throttleType: 'debounce', // 开启选中延迟后调用回调延迟
        throttleDelay: 600, // 选中延迟后调用回调延迟时间
        // 已经选好的选框是否可以被调整形状或平移。默认值为 True
        transformable: false,
      },
      grid: {
        top: '5%',
        left: '3%',
        right: '3%',
        bottom: '15%',
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        splitLine: {
          // 改变横向网格线的颜色
          show: true,
          lineStyle: {
            color: ['rgba(120,140,180,0.8)'],
            width: 1,
            type: 'dashed',
          },
        },
        data: valueData.x,
      },
      yAxis: {
        type: 'value',
        boundaryGap: [0, '100%'],
        splitLine: {
          show: false, // 影藏横向网格线
        },
      },
      dataZoom: [
        {
          type: 'inside',
          start: 0,
          end: 50,
        },
        {
          start: 0,
          end: 50,
        },
      ],
      series: [
        {
          type: 'line',
          itemStyle: {
            color: 'rgb(255, 70, 131)',
          },
          data: valueData.y,
        },
      ],
    };
  }, [valueData, valueData.x, valueData.y]);

  React.useEffect(() => {
    let _data: any[] = [];
    if (secondData) {
      const allValues = Object.values(secondData);
      console.log(allValues);
      for (let i = 0; i < allValues.length; i++) {
        _data = _data.concat(allValues[i]);
      }
      secondDataRef.current = [..._data];
      onBrushChange && onBrushChange([...brushDataRef.current, ..._data]);
    }
  }, [secondData]);

  // 初始化数据
  React.useEffect(() => {
    if (tsRef.current === null) return;

    // 首次渲染时候执行
    if (firstRender.current && defalutData) {
      console.log('defalutData');
      console.log(defalutData);
      // 将初始化数据处理成curLabelRef 数据用于回显
      const _curLabel = curLabel;
      const areas = [];
      for (let i = 0; i < defalutData.length; i++) {
        if (defalutData[i].type !== LABEL_TYPES.TIME_SERIES) {
          const idx = label.findIndex((v) => v.type === defalutData[i].type);

          _curLabel[`${idx}`] = {
            value:
              defalutData[i].type === LABEL_TYPES.MULTIPLE_CHOICES
                ? defalutData[i].value[defalutData[i].type]
                : defalutData[i].value[defalutData[i].type][0],
            color: '',
          };
        } else {
          const fill = rgbaChangeAlpha(defalutData[i].value.color, 0.4);
          const stroke = rgbaChangeAlpha(defalutData[i].value.color, 0.6);
          const _start = valueData.x.findIndex((v: string) => v === defalutData[i].value.start);
          const _end = valueData.x.findIndex((v: string) => v === defalutData[i].value.end);
          const _areas = {
            brushType: 'lineX',
            coordRange: [_start, _end],
            xAxisIndex: 0,
            brushStyle: {
              lineWidth: 1,
              fill,
              stroke,
            },
          };
          areas.push(_areas);
          // 刷子选中的区域回显
          tsRef.current.getEchartsInstance().dispatchAction({
            type: 'brush',
            areas,
          });
        }
      }

      setCurLabel({ ..._curLabel });
      setBrushData([...defalutData]);
      brushDataRef.current = [...defalutData];
      curLabelRef.current = _curLabel;
      firstRender.current = false;
    }
  }, [defalutData, label]);

  // 绑定事件
  React.useEffect(() => {
    if (tsRef.current === null) return;
    // 绑定选中区域的回调
    tsRef.current.getEchartsInstance().off('brushSelected');
    tsRef.current.getEchartsInstance().on('brushSelected', renderBrushed);
    // 绑定节点的点击事件
    tsRef.current.getEchartsInstance().off('click');
    tsRef.current.getEchartsInstance().on('click', renderClick);
  }, [tsRef.current]);

  // 这里只处理Ts类型的数据
  const renderBrushed = (params: any) => {
    console.log('==选中区域数据==');
    console.log(params);
    const mainSeries = params.batch[0].areas;
    console.log('mainSeries');
    console.log(mainSeries);
    if (mainSeries.length === 0) return;
    // 选中区域的横纵标
    const tsItems = brushDataRef.current.filter((v) => v.type === LABEL_TYPES.TIME_SERIES);
    // 单选标签数据
    const singleChoiceItems = brushDataRef.current.filter((v) => v.type === LABEL_TYPES.SINGLE_CHOICES);
    const singleChoiceIdx = brushDataRef.current.findIndex((v) => v.type === LABEL_TYPES.SINGLE_CHOICES);
    // 多选标签数据
    const multipleChoiceItems = brushDataRef.current.filter((v) => v.type === LABEL_TYPES.MULTIPLE_CHOICES);
    const multipleChoiceIdx = brushDataRef.current.findIndex((v) => v.type === LABEL_TYPES.MULTIPLE_CHOICES);

    for (let i = tsItems.length; i < mainSeries.length; i++) {
      if (mainSeries[i].coordRange && mainSeries[i].coordRange.length > 0) {
        const _selectedItems = [];
        for (let j = 0; j < mainSeries[i].coordRange.length; j++) {
          _selectedItems.push(valueData.x[mainSeries[i].coordRange[j]]);
        }
        const _brushData: IbrushData = {
          value: {
            start: _selectedItems[0],
            end: _selectedItems[1],
            [label[curIndexRef.current].type]: [curLabelRef.current[`${curIndexRef.current}`]?.value || ''],
            color: curLabelRef.current[`${curIndexRef.current}`]?.color || '',
          },
          id: Guid().substring(0, 10),
          type: label[curIndexRef.current].type,
        };
        // 如果有二级的key，则将key放到value上
        if (secondKey) {
          _brushData.value.key = secondKey;
        }
        if (title) {
          _brushData.title = title;
        }
        if (topic) {
          _brushData.topic = topic;
        }
        tsItems.push(_brushData);
      }
      // ====将其他类型的数据加上================================================START
      if (singleChoiceIdx >= 0) {
        tsItems.splice(singleChoiceIdx, 0, singleChoiceItems[0]);
      }
      if (multipleChoiceIdx >= 0) {
        tsItems.splice(multipleChoiceIdx, 0, multipleChoiceItems[0]);
      }
      // ====将其他类型的数据加上================================================END

      setBrushData([...tsItems]);
      brushDataRef.current = [...tsItems];

      onBrushChange && onBrushChange([...tsItems, ...secondDataRef.current]);
    }
  };

  // 选中区域之后执行
  React.useEffect(() => {
    console.log('选中区域之后执行');
    if (tsRef.current === null) return;
    if (label[curIndexRef.current].type !== LABEL_TYPES.TIME_SERIES) return;

    const areas = [];
    for (let i = 0; i < brushData.length; i++) {
      if (brushData[i].type === LABEL_TYPES.TIME_SERIES) {
        const fill = rgbaChangeAlpha(brushData[i].value.color, 0.4);
        const stroke = rgbaChangeAlpha(brushData[i].value.color, 0.6);
        const _start = valueData.x.findIndex((v: string) => v === brushData[i].value.start);
        const _end = valueData.x.findIndex((v: string) => v === brushData[i].value.end);
        const _areas = {
          brushType: 'lineX',
          coordRange: [_start, _end],
          xAxisIndex: 0,
          brushStyle: {
            lineWidth: 1,
            fill,
            stroke,
          },
        };
        areas.push(_areas);
      }
    }
    console.log('areas');
    console.log(areas);
    // 刷子选中的区域回显
    tsRef.current.getEchartsInstance().dispatchAction({
      type: 'brush',
      areas,
    });
    // 取消刷子的可以选则的状态
    tsRef.current.getEchartsInstance().dispatchAction({
      type: 'takeGlobalCursor',
    });
    // 取消对应的选中状态
    const _curLabel = curLabel;
    _curLabel[`${curIndex}`] = { value: '', color: '' };
    curLabelRef.current = _curLabel;
    setCurLabel({ ..._curLabel });

    console.log('选中区域之后执行=====结束');
  }, [brushData]);

  // 节点点击回调
  const renderClick = (params: any) => {
    onNodeClick && onNodeClick(params);
  };

  // 标签选择点击事件
  const onSelect = (lb: string, rgb: string, idx: number, type: string) => {
    if (tsRef.current === null) return;

    //  =====设置当前选中的标签==============================================START
    const _curLabel = curLabelRef.current;
    // 多选标签 特殊情况特殊处理
    if (type === LABEL_TYPES.MULTIPLE_CHOICES) {
      let _lb = _curLabel[`${idx}`]?.value || [];
      if (typeof _lb != 'string') {
        const isIdx = _lb.findIndex((v) => v === lb);
        // 如果已经存在，再次点击就取消
        if (isIdx === -1) {
          _lb.push(lb);
        } else {
          _lb = _lb.filter((v) => v !== lb);
        }
      }
      _curLabel[`${idx}`] = {
        value: _lb,
        color: rgb,
      };
      setCurLabel({ ..._curLabel });
      curLabelRef.current = _curLabel;
    } else {
      _curLabel[`${idx}`] = {
        value: lb,
        color: rgb,
      };
      setCurLabel({ ..._curLabel });
      curLabelRef.current = _curLabel;
    }
    //  =====设置当前选中的标签===============================================END

    //  =====对各种类型的标签进行数据处理======================================START
    // 处理ts类型的preview数据
    if (type === LABEL_TYPES.TIME_SERIES) {
      _processTsSelect(rgb);
    }
    // 处理SINGLE_CHOICES类型的preview数据
    if (type === LABEL_TYPES.SINGLE_CHOICES || type === LABEL_TYPES.MULTIPLE_CHOICES) {
      _processSingleChoiceSelect(type);
    }
    //  =====设置当前选中的标签（start）========================================END

    console.log(curLabelRef);
  };

  // 处理ts类型的preview数据
  const _processTsSelect = (rgb: string) => {
    if (tsRef.current === null) return;
    const fill = rgbaChangeAlpha(rgb, 0.4);
    const stroke = rgbaChangeAlpha(rgb, 0.6);
    // 启动刷选
    tsRef.current.getEchartsInstance().dispatchAction({
      type: 'takeGlobalCursor',
      key: 'brush',
      brushOption: {
        brushType: 'lineX',
        brushMode: 'multiple',
        brushStyle: {
          lineWidth: 1,
          fill,
          stroke,
        },
      },
    });
  };

  // 处理choice类型的preview数据
  const _processSingleChoiceSelect = (type: string) => {
    const selectedItems = brushData;
    const _idx = selectedItems.findIndex((v) => v.type === type);
    const _brushData: IbrushData = {
      value: {
        [label[curIndexRef.current].type]:
          type === LABEL_TYPES.MULTIPLE_CHOICES
            ? curLabelRef.current[`${curIndexRef.current}`].value
            : [curLabelRef.current[`${curIndexRef.current}`].value],
      },
      id: _idx >= 0 ? selectedItems[_idx].id : Guid().substring(0, 10), // 如果已经存在ID不变
      type: label[curIndexRef.current].type,
    };
    // 如果有二级的key，则将key放到value上
    if (secondKey) {
      _brushData.value.key = secondKey;
    }
    if (title) {
      _brushData.title = title;
    }
    if (topic) {
      _brushData.topic = topic;
    }
    if (_idx === -1) {
      selectedItems.push(_brushData);
    } else {
      selectedItems[_idx] = _brushData;
    }

    setBrushData([...selectedItems]);
    brushDataRef.current = [...selectedItems];
    onBrushChange && onBrushChange([...selectedItems, ...secondDataRef.current]);
  };

  return (
    <>
      {label.map((lb: any, idx: number) => (
        <Label
          key={Guid()}
          data={lb.data}
          type={lb.type}
          current={curLabel[`${idx}`]?.value || ''}
          onClick={(_lb: string, _rgb: string = '') => {
            setCurIndex(idx);
            curIndexRef.current = idx;
            onSelect(_lb, _rgb, idx, lb.type);
          }}
        />
      ))}
      <ReactEcharts ref={tsRef} option={option} style={{ height: '100%', width: '100%', ...style }} className={className} />
    </>
  );
};

export default TimeSeries;
